<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>多功能工具箱 - 二维码、IP查询、SQL解析、JSON格式化</title>
  <!-- Tailwind CSS -->
  <script src="https://cdn.tailwindcss.com"></script>
  <!-- Font Awesome -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
  <!-- QRCode.js 用于生成二维码 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
  <!-- jsQR 用于解析二维码 -->
  <script src="https://cozmo.github.io/jsQR/jsQR.js"></script>
  
  <script>
    tailwind.config = {
      theme: {
        extend: {
          colors: {
            primary: '#165DFF',
            secondary: '#6B7280',
            success: '#10B981',
            danger: '#EF4444',
            warning: '#F59E0B',
            info: '#3B82F6',
            light: '#F3F4F6',
            dark: '#1F2937'
          },
          fontFamily: {
            sans: ['Inter', 'system-ui', 'sans-serif']
          },
          boxShadow: {
            'card': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
            'card-hover': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)'
          },
          transitionProperty: {
            'height': 'height',
            'spacing': 'margin, padding'
          }
        }
      }
    }
  </script>
  
  <style type="text/tailwindcss">
    @layer utilities {
      .btn-gradient {
        background: linear-gradient(135deg, #165DFF 0%, #0F4CD3 100%);
      }
      .btn-hover:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(22, 93, 255, 0.3);
      }
      .input-focus:focus {
        border-color: #165DFF;
        box-shadow: 0 0 0 3px rgba(22, 93, 255, 0.2);
      }
      .transition-all-300 {
        transition: all 0.3s ease;
      }
      .bg-blur {
        backdrop-filter: blur(8px);
      }
      .tab-active {
        color: #165DFF;
        border-bottom: 2px solid #165DFF;
      }
      .tab-content {
        display: none;
      }
      .tab-content.active {
        display: block;
        animation: fadeIn 0.3s ease;
      }
      .sql-table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 20px;
      }
      .sql-table th, .sql-table td {
        border: 1px solid #ddd;
        padding: 10px;
        text-align: left;
        vertical-align: top;
      }
      .sql-table th {
        background-color: #f2f6fc;
        color: #2c3e50;
      }
      .sql-table td.value {
        font-family: monospace;
      }
      .sql-table td.empty {
        background-color: #fcf0f0;
        color: #c0392b;
        font-weight: bold;
      }
      @keyframes fadeIn {
        from { opacity: 0; transform: translateY(10px); }
        to { opacity: 1; transform: translateY(0); }
      }
      
      /* JSON 语法高亮 */
      .json-key { color: #881391; font-weight: bold; }
      .json-string { color: #c41a16; }
      .json-number { color: #1c00cf; }
      .json-boolean { color: #0d22aa; font-weight: bold; }
      .json-null { color: #808080; font-weight: bold; }
      .json-punctuation { color: #000000; }
    }
  </style>
</head>
<body class="bg-gray-50 min-h-screen">
  <div class="container mx-auto px-4 py-8 max-w-6xl">
    <!-- 标题 -->
    <header class="text-center mb-8">
      <h1 class="text-4xl font-bold text-gray-800 mb-2">多功能工具箱</h1>
      <p class="text-gray-600">二维码生成与解析、IP地址查询、SQL参数解析、JSON格式化</p>
    </header>
    
    <!-- 标签页导航 -->
    <div class="bg-white rounded-t-xl shadow-md mb-1">
      <div class="flex overflow-x-auto">
        <button class="tab-btn tab-active flex-1 py-4 px-6 font-medium text-center transition-all-300" data-tab="generate">
          <i class="fa fa-qrcode mr-2"></i> 生成二维码
        </button>
        <button class="tab-btn flex-1 py-4 px-6 font-medium text-center transition-all-300" data-tab="parse">
          <i class="fa fa-camera mr-2"></i> 解析二维码
        </button>
        <button class="tab-btn flex-1 py-4 px-6 font-medium text-center transition-all-300" data-tab="ip">
          <i class="fa fa-map-marker mr-2"></i> IP地址查询
        </button>
        <button class="tab-btn flex-1 py-4 px-6 font-medium text-center transition-all-300" data-tab="sql">
          <i class="fa fa-database mr-2"></i> SQL解析
        </button>
        <button class="tab-btn flex-1 py-4 px-6 font-medium text-center transition-all-300" data-tab="json">
          <i class="fa fa-code mr-2"></i> JSON格式化
        </button>
      </div>
    </div>
    
    <!-- 标签页内容 -->
    <div class="bg-white rounded-b-xl shadow-card p-6">
      <!-- 生成二维码标签页 -->
      <div id="generate-tab" class="tab-content active">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
          <!-- 左侧：生成表单 -->
          <div>
            <div class="space-y-4">
              <div>
                <label for="qr-text" class="block text-sm font-medium text-gray-700 mb-1">输入文本或URL</label>
                <textarea 
                  id="qr-text" 
                  rows="4" 
                  class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300"
                  placeholder="请输入需要生成二维码的文本或URL..."
                ></textarea>
              </div>
              
              <div class="grid grid-cols-2 gap-4">
                <div>
                  <label for="qr-size" class="block text-sm font-medium text-gray-700 mb-1">二维码大小</label>
                  <select 
                    id="qr-size" 
                    class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300"
                  >
                    <option value="128">小 (128x128)</option>
                    <option value="256" selected>中 (256x256)</option>
                    <option value="384">大 (384x384)</option>
                    <option value="512">特大 (512x512)</option>
                  </select>
                </div>
                
                <div>
                  <label for="qr-color" class="block text-sm font-medium text-gray-700 mb-1">二维码颜色</label>
                  <input 
                    type="color" 
                    id="qr-color" 
                    value="#000000" 
                    class="w-full h-10 rounded-lg cursor-pointer"
                  >
                </div>
              </div>
              
              <div class="flex justify-end">
                <button 
                  id="generate-btn" 
                  class="btn-gradient text-white px-6 py-2 rounded rounded-lg font-medium transition-all-300 btn-hover flex items-center"
                >
                  <i class="fa fa-magic mr-2"></i> 生成二维码
                </button>
              </div>
            </div>
          </div>
          
          <!-- 右侧：生成结果 -->
          <div>
            <div class="flex items-center mb-4">
              <div class="w-10 h-10 rounded-full bg-success/10 flex items-center justify-center mr-3">
                <i class="fa fa-check-circle text-success text-xl"></i>
              </div>
              <h2 class="text-xl font-semibold text-gray-800">生成结果</h2>
            </div>
            
            <div id="generate-result" class="flex flex-col items-center justify-center py-10">
              <div id="qrcode" class="mb-6 bg-white p-4 rounded-lg shadow-sm"></div>
              
              <div id="qrcode-placeholder" class="flex flex-col items-center justify-center py-10">
                <i class="fa fa-qrcode text-6xl text-gray-300 mb-4"></i>
                <p class="text-gray-500">输入文本并点击生成按钮</p>
              </div>
              
              <div id="download-container" class="hidden">
                <a 
                  id="download-btn" 
                  href="#" 
                  download="qrcode.png" 
                  class="bg-success text-white px-6 py-2 rounded-lg font-medium transition-all-300 hover:bg-success/90 flex items-center"
                >
                  <i class="fa fa-download mr-2"></i> 下载二维码
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 解析二维码标签页 -->
      <div id="parse-tab" class="tab-content">
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
          <!-- 左侧：上传区域 -->
          <div>
            <div class="space-y-4">
              <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center hover:border-primary transition-all-300 cursor-pointer" id="drop-area">
                <input type="file" id="file-input" accept="image/*" class="hidden">
                <i class="fa fa-cloud-upload text-4xl text-gray-400 mb-2"></i>
                <p class="text-gray-600">点击或拖拽图片到此处</p>
                <p class="text-xs text-gray-500 mt-1">支持 JPG, PNG, GIF 等格式</p>
              </div>
              
              <div id="uploaded-image-container" class="hidden">
                <div class="relative">
                  <img id="uploaded-image" src="" alt="上传的图片" class="w-full h-auto rounded-lg">
                  <button id="remove-image" class="absolute top-2 right-2 w-8 h-8 rounded-full bg-white/80 flex items-center justify-center shadow-md hover:bg-white transition-all-300">
                    <i class="fa fa-times text-gray-600"></i>
                  </button>
                </div>
              </div>
              
              <div class="flex justify-end">
                <button 
                  id="parse-btn" 
                  class="bg-info text-white px-6 py-2 rounded-lg font-medium transition-all-300 hover:bg-info/90 flex items-center"
                >
                  <i class="fa fa-search mr-2"></i> 解析二维码
                </button>
              </div>
            </div>
          </div>
          
          <!-- 右侧：解析结果 -->
          <div>
            <div class="flex items-center-center mb-4">
              <div class="w-10 h-10 rounded-full-full bg-warning/10 flex items-items-center-center-center-center justify-center mr-3">
                <i class="fa fa-file-text text-warning text-xl"></i>
              </div>
              <h2 class="text-xl font-semibold text-gray-800">解析结果</h2>
            </div>
            
            <div id="parse-result" class="py-10">
              <div id="parse-placeholder" class="flex flex-col items-center justify-center py-10">
                <i class="fa fa-file-text-o text-6xl text-gray-300 mb-4"></i>
                <p class="text-gray-500">上传图片并点击解析按钮</p>
              </div>
              
              <div id="parse-loading" class="hidden flex flex-col items-center justify-center py-10">
                <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary mb-4"></div>
                <p class="text-gray-600">正在解析二维码...</p>
              </div>
              
              <div id="parse-success" class="hidden">
                <div class="bg-green-50 border border-green-200 rounded-lg p-4 mb-4">
                  <div class="flex items-start">
                    <i class="fa fa-check-circle text-green-500 text-xl mr-3 mt-0.5"></i>
                    <div>
                      <h3 class="font-medium text-green-800">解析成功</h3>
                      <p id="parsed-text" class="mt-1 text-green-700 break-words"></p>
                    </div>
                  </div>
                </div>
                
                <div id="parsed-url-container" class="hidden">
                  <a 
                    id="parsed-url" 
                    href="#" 
                    target="_blank" 
                    class="text-primary hover:text-primary/80 font-medium flex items-center"
                  >
                    <i class="fa fa-external-link mr-1"></i> 访问链接
                  </a>
                </div>
              </div>
              
              <div id="parse-error" class="hidden">
                <div class="bg-red-50 border border-red-200 rounded-lg p-4">
                  <div class="flex items-start">
                    <i class="fa fa-exclamation-circle text-red-500 text-xl mr-3 mt-0.5"></i>
                    <div>
                      <h3 class="font-medium text-red-800">解析失败</h3>
                      <p class="mt-1 text-red-700">未能在图片中找到有效的二维码</p>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- IP地址查询标签页 -->
      <div id="ip-tab" class="tab-content">
        <div class="max-w-2xl mx-auto">
          <div class="space-y-4">
            <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
              <div class="flex items-center">
                <i class="fa fa-info-circle text-blue-500 text-xl mr-3"></i>
                <div>
                  <p class="text-blue-800">本地IP: <span id="local-ip" class="font-medium">正在获取...</span></p>
                </div>
              </div>
            </div>
            
            <div>
              <label for="ip-input" class="block text-sm font-medium text-gray-700 mb-1">输入IP地址</label>
              <div class="flex space-x-2">
                <input 
                  type="text" 
                  id="ip-input" 
                  class="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300"
                  placeholder="请输入IP地址，如 114.114.114.114"
                >
                <button 
                  id="query-ip-btn" 
                  class="bg-warning text-white px-6 py-2 rounded-lg font-medium transition-all-300 hover:bg-warning/90 flex items-center"
                >
                  <i class="fa fa-search mr-2"></i> 查询
                </button>
              </div>
            </div>
            
            <div id="ip-result-container" class="hidden">
              <div class="bg-gray-50 border border-gray-200 rounded-lg p-4">
                <h3 class="font-medium text-gray-800 mb-2">查询结果</h3>
                <div id="ip-result" class="space-y-2">
                  <!-- 查询结果将在这里显示 -->
                </div>
              </div>
            </div>
            
            <div id="ip-loading" class="hidden flex items-center justify-center py-4">
              <div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-warning mr-2"></div>
              <p class="text-gray-600">正在查询...</p>
            </div>
            
            <div id="ip-error" class="hidden">
              <div class="bg-red-50 border border-red-200 rounded-lg p-4">
                <div class="flex items-start">
                  <i class="fa fa-exclamation-circle text-red-500 text-xl mr-3 mt-0.5"></i>
                  <div>
                    <h3 class="font-medium text-red-800">查询失败</h3>
                    <p id="ip-error-message" class="mt-1 text-red-700"></p>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <!-- SQL解析标签页 -->
      <div id="sql-tab" class="tab-content">
        <div class="max-w-4xl mx-auto">
          <div class="space-y-4">
            <div class="bg-purple-50 border border-purple-200 rounded-lg p-4">
              <div class="flex items-center">
                <i class="fa fa-info-circle text-purple-500 text-xl mr-3"></i>
                <div>
                  <p class="text-purple-800">用于解析 MyBatis/JDBC 日志中的 UPDATE 语句，快速查看字段更新值。</p>
                </div>
              </div>
            </div>
            
            <div>
              <label for="sql-text" class="block text-sm font-medium text-gray-700 mb-1">SQL 语句</label>
              <textarea 
                id="sql-text" 
                rows="4" 
                class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300 font-mono"
                placeholder="UPDATE table SET col1=?, col2=?, ... WHERE id=?"
              ></textarea>
            </div>
            
            <div>
              <label for="sql-params" class="block text-sm font-medium text-gray-700 mb-1">Parameters 参数</label>
              <textarea 
                id="sql-params" 
                rows="4" 
                class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300 font-mono"
                placeholder="Parameters: value1(String), value2(Long), ..."
              ></textarea>
            </div>
            
            <div class="flex justify-end">
              <button 
                id="parse-sql-btn" 
                class="bg-purple-600 text-white px-6 py-2 rounded-lg font-medium transition-all-300 hover:bg-purple-700 flex items-center"
              >
                <i class="fa fa-table mr-2"></i> 解析为表格
              </button>
            </div>
            
            <div id="sql-result" class="mt-6">
              <!-- SQL解析结果将在这里显示 -->
            </div>
          </div>
        </div>
      </div>
      
      <!-- JSON格式化标签页 -->
      <div id="json-tab" class="tab-content">
        <div class="max-w-6xl mx-auto">
          <div class="space-y-4">
            <div class="bg-indigo-50 border border-indigo-200 rounded-lg p-4">
              <div class="flex items-center">
                <i class="fa fa-info-circle text-indigo-500 text-xl mr-3"></i>
                <div>
                  <p class="text-indigo-800">JSON格式化工具，提供JSON字符串的格式化、压缩、验证和语法高亮功能。</p>
                </div>
              </div>
            </div>
            
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
              <!-- 左侧：输入区域 -->
              <div>
                <div class="space-y-4">
                  <div>
                    <label for="json-input" class="block text-sm font-medium text-gray-700 mb-1">JSON 输入</label>
                    <textarea 
                      id="json-input" 
                      rows="12" 
                      class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none input-focus transition-all-300 font-mono"
                      placeholder='请输入JSON字符串，例如：{"name": "John", "age": 30, "city": "New York"}'
                    ></textarea>
                  </div>
                  
                  <div class="flex flex-wrap gap-2">
                    <button 
                      id="format-json-btn" 
                      class="bg-indigo-600 text-white px-4 py-2 rounded-lg font-medium transition-all-300 hover:bg-indigo-700 flex items-center"
                    >
                      <i class="fa fa-indent mr-2"></i> 格式化
                    </button>
                    <button 
                      id="minify-json-btn" 
                      class="bg-indigo-500 text-white px-4 py-2 rounded-lg font-medium transition-all-300 hover:bg-indigo-600 flex items-center"
                    >
                      <i class="fa fa-compress mr-2"></i> 压缩
                    </button>
                    <button 
                      id="validate-json-btn" 
                      class="bg-green-600 text-white px-4 py-2 rounded-lg font-medium transition-all-300 hover:bg-green-700 flex items-center"
                    >
                      <i class="fa fa-check mr-2"></i> 验证
                    </button>
                    <button 
                      id="clear-json-btn" 
                      class="bg-gray-500 text-white px-4 py-2 rounded-lg font-medium transition-all-300 hover:bg-gray-600 flex items-center"
                    >
                      <i class="fa fa-trash mr-2"></i> 清除
                    </button>
                  </div>
                </div>
              </div>
              
              <!-- 右侧：输出区域 -->
              <div>
                <div class="space-y-4">
                  <div>
                    <label for="json-output" class="block text-sm font-medium text-gray-700 mb-1">格式化结果</label>
                    <pre 
                      id="json-output" 
                      class="w-full h-64 px-4 py-2 border border-gray-300 rounded-lg bg-gray-50 overflow-auto font-mono text-sm"
                    ><code id="json-output-code">格式化后的JSON将显示在这里...</code></pre>
                  </div>
                  
                  <div class="flex justify-between items-center">
                    <div id="json-status" class="text-sm text-gray-600">
                      <!-- JSON验证状态将显示在这里 -->
                    </div>
                    
                    <button 
                      id="copy-json-btn" 
                      class="bg-success text-white px-4 py-2 rounded-lg font-medium transition-all-300 hover:bg-success/90 flex items-center"
                    >
                      <i class="fa fa-copy mr-2"></i> 复制结果
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 页脚 -->
    <footer class="mt-8 text-center text-gray-500 text-sm">
      <p>© 2025 多功能工具箱 | 使用 QRCode.js、jsQR 构建</p>
    </footer>
  </div>
  
  <!-- 通知组件 -->
  <div id="notification" class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 flex items-center z-50">
    <i id="notification-icon" class="mr-2"></i>
    <span id="notification-message"></span>
  </div>
  
  <script>
    // DOM 元素
    const qrText = document.getElementById('qr-text');
    const qrSize = document.getElementById('qr-size');
    const qrColor = document.getElementById('qr-color');
    const generateBtn = document.getElementById('generate-btn');
    const qrcode = document.getElementById('qrcode');
    const qrcodePlaceholder = document.getElementById('qrcode-placeholder');
    const downloadContainer = document.getElementById('download-container');
    const downloadBtn = document.getElementById('download-btn');
    
    const dropArea = document.getElementById('drop-area');
    const fileInput = document.getElementById('file-input');
    const uploadedImageContainer = document.getElementById('uploaded-image-container');
    const uploadedImage = document.getElementById('uploaded-image');
    const removeImage = document.getElementById('remove-image');
    const parseBtn = document.getElementById('parse-btn');
    
    const parsePlaceholder = document.getElementById('parse-placeholder');
    const parseLoading = document.getElementById('parse-loading');
    const parseSuccess = document.getElementById('parse-success');
    const parsedText = document.getElementById('parsed-text');
    const parsedUrlContainer = document.getElementById('parsed-url-container');
    const parsedUrl = document.getElementById('parsed-url');
    const parseError = document.getElementById('parse-error');
    
    // SQL解析相关元素
    const sqlText = document.getElementById('sql-text');
    const sqlParams = document.getElementById('sql-params');
    const parseSqlBtn = document.getElementById('parse-sql-btn');
    const sqlResult = document.getElementById('sql-result');
    
    // JSON格式化相关元素
    const jsonInput = document.getElementById('json-input');
    const jsonOutput = document.getElementById('json-output-code');
    const formatJsonBtn = document.getElementById('format-json-btn');
    const minifyJsonBtn = document.getElementById('minify-json-btn');
    const validateJsonBtn = document.getElementById('validate-json-btn');
    const clearJsonBtn = document.getElementById('clear-json-btn');
    const copyJsonBtn = document.getElementById('copy-json-btn');
    const jsonStatus = document.getElementById('json-status');
    
    const notification = document.getElementById('notification');
    const notificationIcon = document.getElementById('notification-icon');
    const notificationMessage = document.getElementById('notification-message');
    
    // 变量
    let currentQrCode = null;
    let uploadedFile = null;
    
    // 初始化
    function init() {
      // 标签页切换
      const tabBtns = document.querySelectorAll('.tab-btn');
      const tabContents = document.querySelectorAll('.tab-content');
      
      tabBtns.forEach(btn => {
        btn.addEventListener('click', () => {
          const tabId = btn.getAttribute('data-tab');
          
          // 更新标签按钮状态
          tabBtns.forEach(b => b.classList.remove('tab-active'));
          btn.classList.add('tab-active');
          
          // 更新标签内容显示
          tabContents.forEach(content => {
            content.classList.remove('active');
            if (content.id === `${tabId}-tab`) {
              content.classList.add('active');
            }
          });
        });
      });
      
      // 获取并显示本地IP地址
      getLocalIPAddress();
      
      // 生成二维码事件
      generateBtn.addEventListener('click', generateQRCode);
      qrText.addEventListener('input', debounce(generateQRCode, 500));
      qrSize.addEventListener('change', generateQRCode);
      qrColor.addEventListener('change', generateQRCode);
      
      // 解析二维码事件
      dropArea.addEventListener('click', () => fileInput.click());
      fileInput.addEventListener('change', handleFileSelect);
      
      // 拖拽事件
      ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
        dropArea.addEventListener(eventName, preventDefaults, false);
      });
      
      ['dragenter', 'dragover'].forEach(eventName => {
        dropArea.addEventListener(eventName, highlight, false);
      });
      
      ['dragleave', 'drop'].forEach(eventName => {
        dropArea.addEventListener(eventName, unhighlight, false);
      });
      
      dropArea.addEventListener('drop', handleDrop, false);
      
      // 移除图片
      removeImage.addEventListener('click', removeUploadedImage);
      
      // 解析按钮
      parseBtn.addEventListener('click', parseQRCode);
      
      // 下载二维码
      downloadBtn.addEventListener('click', downloadQRCode);
      
      // IP地址查询事件
      const queryIpBtn = document.getElementById('query-ip-btn');
      const ipInput = document.getElementById('ip-input');
      
      queryIpBtn.addEventListener('click', () => {
        const ip = ipInput.value.trim();
        if (ip) {
          queryIPAddress(ip);
        } else {
          showNotification('warning', '请输入IP地址');
        }
      });
      
      // 回车查询
      ipInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
          const ip = ipInput.value.trim();
          if (ip) {
            queryIPAddress(ip);
          } else {
            showNotification('warning', '请输入IP地址');
          }
        }
      });
      
      // SQL解析事件
      parseSqlBtn.addEventListener('click', parseSQL);
      
      // JSON格式化事件
      formatJsonBtn.addEventListener('click', formatJSON);
      minifyJsonBtn.addEventListener('click', minifyJSON);
      validateJsonBtn.addEventListener('click', validateJSON);
      clearJsonBtn.addEventListener('click', clearJSON);
      copyJsonBtn.addEventListener('click', copyJSON);
      
      // JSON输入框自动格式化
      jsonInput.addEventListener('input', debounce(validateJSON, 500));
    }
    
    // 生成二维码
    function generateQRCode() {
      const text = qrText.value.trim();
      const size = parseInt(qrSize.value);
      const color = qrColor.value;
      
      if (!text) {
        clearQRCode();
        showNotification('warning', '请输入文本或URL');
        return;
      }
      
      try {
        // 清除之前的二维码
        clearQRCode();
        
        // 创建新的二维码
        currentQrCode = new QRCode(qrcode, {
          text: text,
          width: size,
          height: size,
          colorDark: color,
          colorLight: '#ffffff',
          correctLevel: QRCode.CorrectLevel.H
        });
        
        // 显示二维码，隐藏占位符
        qrcode.classList.remove('hidden');
        qrcodePlaceholder.classList.add('hidden');
        downloadContainer.classList.remove('hidden');
        
        // 更新下载链接
        updateDownloadLink();
        
        showNotification('success', '二维码生成成功');
      } catch (error) {
        console.error('生成二维码失败:', error);
        showNotification('error', '生成二维码失败，请重试');
      }
    }
    
    // 清除二维码
    function clearQRCode() {
      qrcode.innerHTML = '';
      currentQrCode = null;
      qrcode.classList.add('hidden');
      qrcodePlaceholder.classList.remove('hidden');
      downloadContainer.classList.add('hidden');
    }
    
    // 更新下载链接
    function updateDownloadLink() {
      // 等待二维码生成完成
      setTimeout(() => {
        const canvas = qrcode.querySelector('canvas');
        if (canvas) {
          downloadBtn.href = canvas.toDataURL('image/png');
        }
      }, 100);
    }
    
    // 下载二维码
    function downloadQRCode() {
      if (!currentQrCode) {
        showNotification('warning', '请先生成二维码');
        return;
      }
      
      // 模拟点击下载链接
      downloadBtn.click();
      showNotification('success', '二维码图片已下载');
    }
    
    // 处理文件选择
    function handleFileSelect(e) {
      const file = e.target.files[0];
      if (file) {
        handleFile(file);
      }
    }
    
    // 处理拖拽文件
    function handleDrop(e) {
      const dt = e.dataTransfer;
      const file = dt.files[0];
      if (file) {
        handleFile(file);
      }
    }
    
    // 处理文件
    function handleFile(file) {
      // 检查文件类型
      if (!file.type.match('image.*')) {
        showNotification('warning', '请上传图片文件');
        return;
      }
      
      uploadedFile = file;
      
      // 显示上传的图片
      const reader = new FileReader();
      reader.onload = (e) => {
        uploadedImage.src = e.target.result;
        uploadedImageContainer.classList.remove('hidden');
        dropArea.classList.add('hidden');
        
        // 重置解析结果
        resetParseResult();
      };
      reader.readAsDataURL(file);
    }
    
    // 移除上传的图片
    function removeUploadedImage() {
      uploadedFile = null;
      uploadedImage.src = '';
      uploadedImageContainer.classList.add('hidden');
      dropArea.classList.remove('hidden');
      
      // 重置解析结果
      resetParseResult();
    }
    
    // 解析二维码
    function parseQRCode() {
      if (!uploadedFile) {
        showNotification('warning', '请先上传图片');
        return;
      }
      
      // 显示加载状态
      showParseLoading();
      
      // 读取图片
      const reader = new FileReader();
      reader.onload = (e) => {
        const img = new Image();
        img.onload = () => {
          try {
            // 创建画布
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            
            // 设置画布大小
            canvas.width = img.width;
            canvas.height = img.height;
            
            // 绘制图片
            ctx.drawImage(img, 0, 0);
            
            // 获取图片数据
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            
            // 尝试解析二维码
            let code = jsQR(imageData.data, imageData.width, imageData.height);
            
            if (code) {
              // 解析成功
              handleParseSuccess(code.data);
            } else {
              // 尝试使用灰度图像解析
              const grayImageData = convertToGrayscale(imageData);
              code = jsQR(grayImageData.data, grayImageData.width, grayImageData.height);
              
              if (code) {
                handleParseSuccess(code.data);
              } else {
                // 尝试缩小图像解析
                const scaledImageData = scaleImageData(imageData, 0.5);
                code = jsQR(scaledImageData.data, scaledImageData.width, scaledImageData.height);
                
                if (code) {
                  handleParseSuccess(code.data);
                } else {
                  // 解析失败
                  handleParseError();
                }
              }
            }
          } catch (error) {
            console.error('解析二维码失败:', error);
            handleParseError();
          }
        };
        img.onerror = () => {
          console.error('加载图片失败');
          handleParseError();
        };
        img.src = e.target.result;
      };
      reader.onerror = () => {
        console.error('读取文件失败');
        handleParseError();
      };
      reader.readAsDataURL(uploadedFile);
    }
    
    // 处理解析成功
    function handleParseSuccess(data) {
      console.log('解析成功:', data);
      
      // 隐藏加载状态
      parseLoading.classList.add('hidden');
      
      // 显示成功结果
      parsedText.textContent = data;
      parseSuccess.classList.remove('hidden');
      
      // 检查是否是否为URL
      if (isValidUrl(data)) {
        parsedUrl.href = data;
        parsedUrlContainer.classList.remove('hidden');
      } else {
        parsedUrlContainer.classList.add('hidden');
      }
      
      showNotification('success', '二维码解析成功');
    }
    
    // 处理解析失败
    function handleParseError() {
      console.log('解析失败');
      
      // 隐藏加载状态
      parseLoading.classList.add('hidden');
      
      // 显示错误结果
      parseError.classList.remove('hidden');
      
      showNotification('error', '未能识别二维码，请确保图片清晰');
    }
    
    // 显示解析加载状态
    function showParseLoading() {
      resetParseResult();
      parseLoading.classList.remove('hidden');
    }
    
    // 重置解析结果
    function resetParseResult() {
      parsePlaceholder.classList.add('hidden');
      parseLoading.classList.add('hidden');
      parseSuccess.classList.add('hidden');
      parseError.classList.add('hidden');
      parsedUrlContainer.classList.add('hidden');
    }
    
    // 检查是否是有效的URL
    function isValidUrl(url) {
      try {
        new URL(url);
        return true;
      } catch (e) {
        return false;
      }
    }
    
    // 转换为灰度图像
    function convertToGrayscale(imageData) {
      const data = imageData.data;
      const width = imageData.width;
      const height = imageData.height;
      
      const grayCanvas = document.createElement('canvas');
      grayCanvas.width = width;
      grayCanvas.height = height;
      const grayCtx = grayCanvas.getContext('2d');
      
      grayCtx.putImageData(imageData, 0, 0);
      
      const grayImageData = grayCtx.getImageData(0, 0, width, height);
      const grayData = grayImageData.data;
      
      for (let i = 0; i < data.length; i += 4) {
        const gray = Math.round(0.2989 * data[i] + 0.5870 * data[i + 1] + 0.1140 * data[i + 2]);
        grayData[i] = gray;
        grayData[i + 1] = gray;
        grayData[i + 2] = gray;
      }
      
      return grayImageData;
    }
    
    // 缩小图像
    function scaleImageData(imageData, scale) {
      const width = imageData.width;
      const height = imageData.height;
      const scaledWidth = Math.round(width * scale);
      const scaledHeight = Math.round(height * scale);
      
      const scaledCanvas = document.createElement('canvas');
      scaledCanvas.width = scaledWidth;
      scaledCanvas.height = scaledHeight;
      const scaledCtx = scaledCanvas.getContext('2d');
      
      const tempCanvas = document.createElement('canvas');
      tempCanvas.width = width;
      tempCanvas.height = height;
      const tempCtx = tempCanvas.getContext('2d');
      
      tempCtx.putImageData(imageData, 0, 0);
      
      scaledCtx.drawImage(tempCanvas, 0, 0, width, height, 0, 0, scaledWidth, scaledHeight);
      
      return scaledCtx.getImageData(0, 0, scaledWidth, scaledHeight);
    }
    
    // SQL解析功能
    function parseSQL() {
      const sql = sqlText.value.trim();
      const paramsLine = sqlParams.value.trim();
      
      if (!sql || !paramsLine) {
        showNotification('warning', '请填写 SQL 和 Parameters！');
        return;
      }
      
      // 提取 SET 和 WHERE 之间的字段
      const setMatch = sql.match(/SET\s+(.+?)\s+WHERE/is);
      if (!setMatch) {
        showNotification('error', '无法解析 SQL：请检查格式是否正确（包含 SET ... WHERE）');
        return;
      }
      
      const setClause = setMatch[1];
      const fieldNames = setClause
        .split(',')
        .map(part => part.trim().split('=')[0].trim());
      
      // 提取 Parameters 的值（去除 (Type) 类型）
      const paramsText = paramsLine.replace(/Parameters:\s*/i, '').trim();
      const paramValues = paramsText
        .split(',')
        .map(val => {
          // 去除 (String), (Long) 等类型标注
          return val.replace(/\s*\([^)]*\)/g, '').trim();
        });
      
      // 检查字段和参数数量是否匹配
      if (fieldNames.length !== paramValues.length) {
        showNotification('warning', `字段数量 (${fieldNames.length}) 与参数数量 (${paramValues.length}) 不匹配！`);
      }
      
      // 生成表格
      let tableHTML = `
        <h3 class="text-lg font-semibold text-gray-800 mb-4">解析结果（共 ${fieldNames.length} 个字段）</h3>
        <table class="sql-table">
          <tr><th>字段名</th><th>更新后的值</th></tr>
      `;
      
      for (let i = 0; i < fieldNames.length; i++) {
        const field = fieldNames[i];
        const value = paramValues[i];
        const isEmpty = !value || value === 'null' ? 'empty' : '';
        tableHTML += `
          <tr>
            <td class="font-medium">${field}</td>
            <td class="value ${isEmpty}">${value || '(空)'}</td>
          </tr>
        `;
      }
      
      tableHTML += `</table>`;
      
      // 添加复制按钮
      tableHTML += `
        <button id="copy-sql-result" class="bg-success text-white px-4 py-2 rounded-lg font-medium mt-4 transition-all-300 hover:bg-success/90 flex items-center">
          <i class="fa fa-copy mr-2"></i> 复制为文本
        </button>
      `;
      
      sqlResult.innerHTML = tableHTML;
      
      // 绑定复制功能
      document.getElementById('copy-sql-result').addEventListener('click', () => {
        const copyText = fieldNames.map((f, i) => `${f} = ${paramValues[i] || '(空)'}`).join('\n');
        navigator.clipboard.writeText(copyText).then(() => {
          showNotification('success', '已复制到剪贴板！');
        }).catch(err => {
          console.error('复制失败:', err);
          showNotification('error', '复制失败');
        });
      });
      
      showNotification('success', 'SQL解析完成');
    }
    
    // JSON格式化功能
    function formatJSON() {
      try {
        const input = jsonInput.value.trim();
        if (!input) {
          showNotification('warning', '请输入JSON字符串');
          return;
        }
        
        const parsed = JSON.parse(input);
        const formatted = JSON.stringify(parsed, null, 2);
        
        // 应用语法高亮
        jsonOutput.innerHTML = syntaxHighlight(formatted);
        
        // 更新状态
        jsonStatus.innerHTML = '<span class="text-green-600"><i class="fa fa-check mr-1"></i> JSON格式正确</span>';
        
        showNotification('success', 'JSON格式化成功');
      } catch (error) {
        jsonOutput.textContent = 'JSON格式错误：' + error.message;
        jsonStatus.innerHTML = '<span class="text-red-600"><i class="fa fa-exclamation-triangle mr-1"></i> JSON格式错误</span>';
        showNotification('error', 'JSON格式错误');
      }
    }
    
    // JSON压缩功能
    function minifyJSON() {
      try {
        const input = jsonInput.value.trim();
        if (!input) {
          showNotification('warning', '请输入JSON字符串');
          return;
        }
        
        const parsed = JSON.parse(input);
        const minified = JSON.stringify(parsed);
        
        // 应用语法高亮
        jsonOutput.innerHTML = syntaxHighlight(minified);
        
        // 更新状态
        jsonStatus.innerHTML = '<span class="text-green-600"><i class="fa fa-check mr-1"></i> JSON压缩成功</span>';
        
        showNotification('success', 'JSON压缩成功');
      } catch (error) {
        jsonOutput.textContent = 'JSON格式错误：' + error.message;
        jsonStatus.innerHTML = '<span class="text-red-600"><i class="fa fa-exclamation-triangle mr-1"></i> JSON格式错误</span>';
        showNotification('error', 'JSON格式错误');
      }
    }
    
    // JSON验证功能
    function validateJSON() {
      try {
        const input = jsonInput.value.trim();
        if (!input) {
          jsonStatus.innerHTML = '<span class="text-gray-600">请输入JSON字符串</span>';
          jsonOutput.textContent = '请输入JSON字符串...';
          return;
        }
        
        JSON.parse(input);
        
        // 如果验证通过，也格式化显示
        const parsed = JSON.parse(input);
        const formatted = JSON.stringify(parsed, null, 2);
        jsonOutput.innerHTML = syntaxHighlight(formatted);
        
        jsonStatus.innerHTML = '<span class="text-green-600"><i class="fa fa-check mr-1"></i> JSON格式正确</span>';
      } catch (error) {
        jsonOutput.textContent = 'JSON格式错误：' + error.message;
        jsonStatus.innerHTML = '<span class="text-red-600"><i class="fa fa-exclamation-triangle mr-1"></i> JSON格式错误</span>';
      }
    }
    
    // 清除JSON
    function clearJSON() {
      jsonInput.value = '';
      jsonOutput.textContent = '格式化后的JSON将显示在这里...';
      jsonStatus.innerHTML = '';
      showNotification('info', '已清除JSON内容');
    }
    
    // 复制JSON结果
    function copyJSON() {
      const text = jsonOutput.textContent;
      if (!text || text === '格式化后的JSON将显示在这里...') {
        showNotification('warning', '没有可复制的内容');
        return;
      }
      
      navigator.clipboard.writeText(text).then(() => {
        showNotification('success', '已复制到剪贴板');
      }).catch(err => {
        console.error('复制失败:', err);
        showNotification('error', '复制失败');
      });
    }
    
    // JSON语法高亮
    function syntaxHighlight(json) {
      if (typeof json !== 'string') {
        json = JSON.stringify(json, null, 2);
      }
      
      // 转义HTML特殊字符
      json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
      
      // 应用语法高亮
      return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
        let cls = 'json-number';
        if (/^"/.test(match)) {
          if (/:$/.test(match)) {
            cls = 'json-key';
          } else {
            cls = 'json-string';
          }
        } else if (/true|false/.test(match)) {
          cls = 'json-boolean';
        } else if (/null/.test(match)) {
          cls = 'json-null';
        }
        return '<span class="' + cls + '">' + match + '</span>';
      });
    }
    
    // 显示通知
    function showNotification(type, message) {
      // 设置通知类型
      let iconClass = '';
      let bgColor = '';
      
      switch (type) {
        case 'success':
          iconClass = 'fa fa-check-circle text-white';
          bgColor = 'bg-green-500';
          break;
        case 'error':
          iconClass = 'fa fa-exclamation-circle text-white';
          bgColor = 'bg-red-500';
          break;
        case 'warning':
          iconClass = 'fa fa-exclamation-triangle text-white';
          bgColor = 'bg-yellow-500';
          break;
        default:
          iconClass = 'fa fa-info-circle text-white';
          bgColor = 'bg-blue-500';
      }
      
      // 设置通知内容
      notificationIcon.className = iconClass;
      notificationMessage.textContent = message;
      
      // 设置通知样式
      notification.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg transform translate-y-0 opacity-100 transition-all duration-300 flex items-center z-50 ${bgColor}`;
      
      // 3秒后隐藏通知
      setTimeout(() => {
        notification.className = 'fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg transform translate-y-20 opacity-0 transition-all duration-300 flex items-center z-50';
      }, 3000);
    }
    
    // 防抖函数
    function debounce(func, wait) {
      let timeout;
      return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
          func.apply(context, args);
        }, wait);
      };
    }
    
    // 获取本地IP地址
    function getLocalIPAddress() {
      const localIpElement = document.getElementById('local-ip');
      
      if (!localIpElement) {
        console.error('未找到本地IP显示元素');
        return;
      }
      
      // 定义多个可靠的IP获取API
      const ipApis = [
        'https://api.ipify.org?format=json',
        'https://api64.ipify.org?format=json',
        'https://icanhazip.com',
        'https://checkip.amazonaws.com',
        'https://ipinfo.io/ip'
      ];
      
      // 尝试获取IP地址的函数
      function tryGetIP(apiIndex = 0) {
        if (apiIndex >= ipApis.length) {
          // 所有API都尝试过了，仍然失败
          localIpElement.textContent = '获取失败';
          return;
        }
        
        const apiUrl = ipApis[apiIndex];
        
        fetch(apiUrl)
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP错误! 状态码: ${response.status}`);
            }
            
            // 根据API返回格式处理响应
            if (apiUrl.includes('format=json')) {
              return response.json();
            } else {
              return response.text().then(text => ({ ip: text.trim() }));
            }
          })
          .then(data => {
            if (data.ip && isValidIP(data.ip)) {
              localIpElement.textContent = data.ip;
              
              // 自动填充到IP输入框
              const ipInput = document.getElementById('ip-input');
              if (ipInput && !ipInput.value) {
                ipInput.value = data.ip;
              }
            } else {
              // IP格式无效，尝试下一个API
              throw new Error('获取的IP格式无效');
            }
          })
          .catch(error => {
            console.error(`使用API ${apiUrl} 获取IP失败:`, error);
            // 尝试下一个API
            tryGetIP(apiIndex + 1);
          });
      }
      
      // 检查IP地址格式是否有效
      function isValidIP(ip) {
        // 简单的IP地址格式验证
        const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
        const ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
        return ipv4Regex.test(ip) || ipv6Regex.test(ip);
      }
      
      // 开始尝试获取IP地址
      tryGetIP();
    }
    
    // IP地址查询函数
    function queryIPAddress(ip) {
      const ipResultContainer = document.getElementById('ip-result-container');
      const ipResult = document.getElementById('ip-result');
      const ipLoading = document.getElementById('ip-loading');
      const ipError = document.getElementById('ip-error');
      const ipErrorMessage = document.getElementById('ip-error-message');
      
      // 隐藏所有结果容器
      ipResultContainer.classList.add('hidden');
      ipError.classList.add('hidden');
      
      // 显示加载动画
      ipLoading.classList.remove('hidden');
      
      // 构建IP地址查询API
      const apiUrl = `http://ip-api.com/json/${ip}?lang=zh-CN`;
      
      fetch(apiUrl)
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          // 隐藏加载动画
          ipLoading.classList.add('hidden');
          
          if (data.status === 'success') {
            // 显示查询结果
            ipResult.innerHTML = `
              <div class="grid grid-cols-2 gap-2">
                <div class="text-sm text-gray-600">IP地址:</div>
                <div class="text-sm font-medium">${data.query}</div>
                
                <div class="text-sm text-gray-600">国家:</div>
                <div class="text-sm font-medium">${data.country}</div>
                
                <div class="text-sm text-gray-600">地区:</div>
                <div class="text-sm font-medium">${data.regionName}</div>
                
                <div class="text-sm text-gray-600">城市:</div>
                <div class="text-sm font-medium">${data.city}</div>
                
                <div class="text-sm text-gray-600">运营商:</div>
                <div class="text-sm font-medium">${data.isp}</div>
                
                <div class="text-sm text-gray-600">经纬度:</div>
                <div class="text-sm font-medium">${data.lat}, ${data.lon}</div>
              </div>
            `;
            
            ipResultContainer.classList.remove('hidden');
            showNotification('success', 'IP地址查询成功');
          } else {
            // 显示错误信息
            ipErrorMessage.textContent = data.message || '查询失败，请稍后重试';
            ipError.classList.remove('hidden');
            showNotification('error', 'IP地址查询失败');
          }
        })
        .catch(error => {
          // 隐藏加载动画
          ipLoading.classList.add('hidden');
          
          // 显示错误信息
          ipErrorMessage.textContent = `查询失败: ${error.message}`;
          ipError.classList.remove('hidden');
          showNotification('error', 'IP地址查询失败');
          console.error('IP地址查询错误:', error);
        });
    }
    
    // 阻止默认行为
    function preventDefaults(e) {
      e.preventDefault();
      e.stopPropagation();
    }
    
    // 高亮拖拽区域
    function highlight() {
      dropArea.classList.add('border-primary');
    }
    
    // 取消高亮拖拽区域
    function unhighlight() {
      dropArea.classList.remove('border-primary');
    }
    
    // 页面加载完成后初始化
    document.addEventListener('DOMContentLoaded', init);
  </script>
</body>
</html>